package com.haltakov.letterjumble.client;

/* Watcher monitors the stream coming from the server
 which will contain messages that must be processed by 
 the client (a NetFourByFour object)

 Incoming Messages:
 ok <playerID>           -- connection accepted; include player ID
 full                    -- connection refused; server has enough players
 tooFewPlayers           -- turn rejected, since not enough players
 otherTurn <player> <posn>  -- turn by other player sent to client
 added <player>          -- other player added to server
 removed <player>        -- other player removed
 */

import java.io.*;
import java.util.*;
import java.util.List;

import com.haltakov.letterjumble.game.api.BoardWord;
import com.haltakov.letterjumble.game.api.GameController;
import com.haltakov.letterjumble.game.api.HumanPlayer;
import com.haltakov.letterjumble.game.api.Letter;
import com.haltakov.letterjumble.game.api.PlayerType;
import com.haltakov.letterjumble.game.api.WordDirection;

public class LetterJumbleWatcher extends Thread {

	private GameController gameController;
	private BufferedReader in;

	public LetterJumbleWatcher(GameController gameController, BufferedReader i) {
		this.gameController = gameController;
		in = i;
	}

	// Read server messages and act on them
	public void run() {

		String line;
		try {
			while ((line = in.readLine()) != null) {
				if (line.startsWith("ok")) { // connection is accepted, client gets its playerID, current player is added
					int id = extractID(line.substring(3));
					gameController.setPlayerID(id);
					gameController.addPlayer(new HumanPlayer(gameController, "Me" , PlayerType.HUMAN), id);		
				} else if(line.startsWith("previously added")) {
					int id = extractID(line.substring(17));
					gameController.addPreviousPlayers(id);
				}
				else if (line.startsWith("full")) {
					gameController.disable("full game"); // disable client
				}
				else if (line.startsWith("tooFewPlayers")) {
					gameController.disable("other player has left"); // disable client	
				}
				else if (line.startsWith("otherTurn")) {
					System.out.println("EXTRTRACT OTHER TURN");
					extractOtherTurn(line.substring(10));
					//extractOther(line.substring(10));
				}
				else if (line.startsWith("added")) {
					int id = extractID(line.substring(6));
					gameController.addOtherPlayer(new HumanPlayer(gameController, "Player " + id, PlayerType.HUMAN), id);
				}
				else if (line.startsWith("start")) {
					System.out.println("Start: my player is " + gameController.getPlayerID());
					int id = extractID(line.substring(6));
					gameController.initiateGame(id); 
				}
				else if (line.startsWith("removed"))  {// don't use ID, client removes other player
					gameController.removePlayer();  
				}
				else { // anything else
					System.out.println("ERR: " + line + "\n");
				}
			}
		} catch (Exception e) // socket closure will cause termination of while
		{ // System.out.println("Socket closed");
			//e.printStackTrace()
			gameController.disable("server link lost"); // end game as well
			e.printStackTrace();
		}
	} // end of run()

	private int extractID(String line) {
		int id = -1;
		StringTokenizer tokens = new StringTokenizer(line);
		try {
			id = Integer.parseInt(tokens.nextToken());
		} catch (NumberFormatException e) {
			System.out.println(e);
		}
		return id;
	}

	private void extractOther(String line)
	// line format: <player id> <posn>
	{
		StringTokenizer tokens = new StringTokenizer(line);
		try {
			int playerID = Integer.parseInt(tokens.nextToken());
			int posn = Integer.parseInt(tokens.nextToken());
			//gameController.doMove(posn, playerID); // client executes the other
													// player's move
		} catch (NumberFormatException e) {
			System.out.println(e);
		}
	} 

	public void extractOtherTurn(String move) {
		
		System.out.println("MOVE: " + move);
		String[] moveElements = move.split(" ");
		int x = Integer.parseInt(moveElements[0]);
		int y = Integer.parseInt(moveElements[1]);
		WordDirection direction = WordDirection.valueOf(moveElements[2]);
		int score = Integer.parseInt(moveElements[3]);
		List<Letter> letters = new ArrayList<Letter>();
		String lettersStr = moveElements[4];
		String[] lettersArr = lettersStr.split(",");
		for(String l : lettersArr) {
			if(l != null && !l.equals("")) {
				letters.add(new Letter(new Character(l.split(":")[0].charAt(0)), Integer.valueOf(l.split(":")[1]), Integer.valueOf(l.split(":")[2])));
			}
		}
		Letter[] lettt = new Letter[letters.size()];
		int index = 0;
		for(Letter l : letters) {
			lettt[index] = l;
			index++;
		}
		BoardWord word = new BoardWord(gameController.getBoard(), lettt, x, y, direction);
		gameController.otherPlayed(word);
	}
} 

